﻿/*  Francis Nino Seisei 
 *  ©2012 Francis Antonio Bolaños Arias.
 * 
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Text;
using Seisei.Global;

namespace Seisei.Nino.Generator
{
    public class MSSQL
    {
        public static string[] GetDatabases()
        {
            try
            {
                //Creamos el ConnectionString con los params.
                SqlConnection ConnectionString = new SqlConnection();
                ConnectionString.ConnectionString = "Data Source=" + Memory.Server + " ;Initial Catalog=master;" + "User ID="
                    + Memory.User + ";Password=" + Memory.Pass;
                //Declaracion de un adapter y una datatable.
                SqlDataAdapter Adaptar = new SqlDataAdapter();
                DataTable Tabla = new DataTable("Tabla1");
                //Entero que va a contener la vantidad de rows que tiene la tabla.
                int Registros;
                //Declaracion del comando para obtener las categorias.
                SqlCommand comando = new SqlCommand();
                comando.CommandText = "SELECT name from master..sysdatabases";
                //Se ejecuta la conexion con el comando.
                comando.Connection = ConnectionString;
                //Se llena el adapter.
                Adaptar.SelectCommand = comando;
                //Y se llena la tabla con el adapter.
                Adaptar.Fill(Tabla);
                //Luego se le asigna a registros el numero de filas (rows de la tabla).
                ConnectionString.Close();
                Registros = Tabla.Rows.Count;
                //Se crea un vector del tama;o de los registros (de la cantidad que hay).
                string[] VectorCate = new String[Registros];
                //Y un entero para manejar ciclos
                int i = 0;
                //Condicion de continuacion
                while (i < Registros)
                {
                    //Se llena la tabla en cada posicion con los datos del vector.
                    VectorCate[i] = Tabla.Rows[i][0].ToString();
                    //Se incrementa el i para qeu aumente el numero que va a guardar la tabla.
                    i += 1;
                    //Fin de ciclo cuando se cumpla todo.
                }
                //Retorna el vector.
                return VectorCate;
                //Fin de funcion.
            }
            catch (Exception)
            {
                //MessageBox.Show(ex.Message.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            return null;
        }

        public static string[] GetTables()
        {
            try
            {
                //Declaracion de un adapter y una datatable.
                SqlDataAdapter Adaptar = new SqlDataAdapter();
                DataTable Tabla = new DataTable("table_name");
                //Entero que va a contener la vantidad de rows que tiene la tabla.
                int Registros;
                //Declaracion del comando para obtener las categorias.
                SqlCommand comando = new SqlCommand();
                comando.CommandText = "SELECT table_schema, table_name FROM Information_Schema.Tables where Table_Type = 'BASE TABLE'";
                //Se ejecuta la conexion con el comando.

                comando.Connection = new SqlConnection("Data Source=" + Memory.Server + " ;Initial Catalog=" + Memory.Database + ";"
                    + "User ID=" + Memory.User + ";Password=" + Memory.Pass);
                //Se llena el adapter.
                Adaptar.SelectCommand = comando;
                //Y se llena la tabla con el adapter.
                Adaptar.Fill(Tabla);
                //Luego se le asigna a registros el numero de filas (rows de la tabla).
                Registros = Tabla.Rows.Count;
                //Se crea un vector del tamaño de los registros (de la cantidad que hay).
                string[] VectorCate = new string[Registros];
                //Y un entero para manejar ciclos.
                int i = 0;
                //Condicion de continuacion.
                while (i < Registros)
                {
                    //Se llena la tabla en cada posicion con los datos del vector.
                    if (!Tabla.Rows[i][0].Equals("dbo"))
                    {
                        VectorCate[i] = Tabla.Rows[i][0] + ".";
                    }
                    VectorCate[i] += Tabla.Rows[i][1];
                    //Se incrementa el i para que aumente el numero que va a guardar la tabla. 
                    i += 1;
                    //Fin de ciclo cuando se cumpla todo.
                }
                //Retorna el vector. 
                return VectorCate;
                //Fin de funcion.
            }
            catch (Exception)
            {
                //MessageBox.Show(ex.Message.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            return null;
        }

        public static string GetNinoHeaderCode()
        {
            return "/*\n" +
                   " * Francis Nino Seisei Code Output \n" +
                   " */\n" +
                   "\n" +
                   "/* Setting authentication data*/\n" +
                   "SET DB_SERVER AS " + Memory.Server + ";\n" +
                   "SET DB_USER AS " + Memory.User + ";\n" +
                   "SET DB_USER_PASS AS " + Memory.Pass + ";\n" +
                   "\n" +
                   "/* Database that will be used*/\n" +
                   "SET DATABASE AS " + Memory.Database + ";\n" +
                   "\n";
        }

        public static string GetTableNINOCode(string Tabla)
        {
            string datosUnidos = "/* Structure for table '" + Tabla + "'*/\n"
                + "TABLE " + "[" + Tabla.Replace(" ", "_") + "](\n";
            try
            {
                //Nuevo comando  
                SqlCommand comando = new SqlCommand();
                //Asignar la conexión al comand y la consulta sql  
                comando.Connection = new SqlConnection("Data Source=" + Memory.Server + " ;Initial Catalog=" + Memory.Database + ";"
                    + "User ID=" + Memory.User + ";Password=" + Memory.Pass);

                string schema = "";
                if (Tabla.Contains("."))
                {
                    string[] aux = Tabla.Split('.');
                    schema = aux[0];
                    comando.CommandText = "EXEC sp_help " + "'[" + aux[0] + "].[" + aux[1] + "]'";
                }
                else
                {
                    schema = "dbo";
                    comando.CommandText = "EXEC sp_help " + "'[dbo].[" + Tabla + "]'";
                }

                SqlDataAdapter adaptador = new SqlDataAdapter();
                adaptador.SelectCommand = comando;
                DataSet ds = new DataSet();
                adaptador.Fill(ds);
                int i = 0;
                foreach (DataTable dt in ds.Tables)
                {
                    if (i == 1)
                    {
                        int j = 0;
                        foreach (DataRow dr in dt.Rows)
                        {
                            string nullable = "NULL";
                            string dataLength = "";
                            if (dt.Rows[j]["Type"].ToString().Equals("binary")
                                || dt.Rows[j]["Type"].ToString().Equals("char")
                                || dt.Rows[j]["Type"].ToString().Equals("datetime2")
                                || dt.Rows[j]["Type"].ToString().Equals("datetimeoffset")
                                || dt.Rows[j]["Type"].ToString().Equals("nchar")
                                || dt.Rows[j]["Type"].ToString().Equals("nvarchar")
                                || dt.Rows[j]["Type"].ToString().Equals("time")
                                || dt.Rows[j]["Type"].ToString().Equals("varbinary")
                                || dt.Rows[j]["Type"].ToString().Equals("varchar"))
                            {
                                dataLength = "(" + dt.Rows[j]["Length"].ToString() + ")";
                            }
                            else if (dt.Rows[j]["Type"].ToString().Equals("decimal")
                               || dt.Rows[j]["Type"].ToString().Equals("numeric"))
                            {
                                dataLength = "(" + dt.Rows[j]["Prec"].ToString().Trim() + "," + dt.Rows[j]["Scale"].ToString().Trim() + ")";
                            }
                            if (dt.Rows[j]["Nullable"].ToString().Equals("no"))
                            {
                                nullable = "NOT NULL";
                            }
                            datosUnidos += "    " + dt.Rows[j]["Column_name"].ToString().Replace(" ", "_") + " " + dt.Rows[j]["Type"].ToString().ToUpper()
                                + dataLength + " " + nullable + ";\n";
                            j++;
                        }
                    }
                    if (i == 2)
                    {
                        int j = 0;
                        foreach (DataRow dr in dt.Rows)
                        {
                            if (!dt.Rows[j]["Identity"].ToString().Equals("No identity column defined."))
                            {
                                datosUnidos += "    IDENTITY ON " + dt.Rows[j]["Identity"].ToString() + ";\n";
                                j++;
                            }
                        }
                    }
                    if (i == 5)
                    {
                        try
                        {
                            int j = 0;
                            foreach (DataRow dr in dt.Rows)
                            {
                                if (dt.Rows[j]["constraint_type"].ToString().Contains("PRIMARY KEY"))
                                {
                                    datosUnidos += "    PRIMARY KEY " + dt.Rows[j]["constraint_keys"].ToString() + ";\n";
                                }
                                else if (dt.Rows[j]["constraint_type"].ToString().Equals("FOREIGN KEY"))
                                {
                                    datosUnidos += "    FOREIGN KEY " + dt.Rows[j]["constraint_keys"].ToString() + " FROM "
                                        + dt.Rows[j + 1]["constraint_keys"].ToString().Replace("REFERENCES " + Memory.Database + ".", "").Replace(
                                        dt.Rows[j + 1]["constraint_keys"].ToString().Substring(
                                        dt.Rows[j + 1]["constraint_keys"].ToString().IndexOf('(')
                                        )
                                        , "").Replace("dbo.", "").Trim() + ";\n";
                                }
                                j += 2;
                            }
                        }
                        catch (Exception) { }
                    }
                    if (i == 6)
                    {
                        try
                        {
                            int j = 0;
                            foreach (DataRow dr in dt.Rows)
                            {
                                if (dt.Rows[j]["constraint_type"].ToString().Contains("PRIMARY KEY"))
                                {
                                    datosUnidos += "    PRIMARY KEY " + dt.Rows[j]["constraint_keys"].ToString() + ";\n";
                                }
                                else if (dt.Rows[j]["constraint_type"].ToString().Equals("FOREIGN KEY"))
                                {
                                    datosUnidos += "    FOREIGN KEY " + dt.Rows[j]["constraint_keys"].ToString() + " FROM "
                                        + dt.Rows[j + 1]["constraint_keys"].ToString().Replace("REFERENCES " + Memory.Database + ".", "").Replace(
                                        dt.Rows[j + 1]["constraint_keys"].ToString().Substring(
                                        dt.Rows[j + 1]["constraint_keys"].ToString().IndexOf('(')
                                        )
                                        , "").Replace("dbo.", "").Trim() + ";\n";
                                }
                                j += 2;
                            }
                        }
                        catch (Exception) { }
                    }
                    i++;
                }

                return datosUnidos += ")\n";
            }
            catch (Exception e)
            {
                return datosUnidos + e.Message;
            }
        }
    }
}
